home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / TSR / TPPOP18C / UNHOOK.PAS < prev    next >
Pascal/Delphi Source File  |  1988-11-08  |  5KB  |  176 lines

  1. {$A+,B-,D+,E-,F-,I+,L+,N-,O-,R-,S-,V-}
  2. Unit Unhook;
  3.  
  4. { Copyright (c)1988 Ross Neilson Wentworth                           }
  5. {                   Serendipity Software                             }
  6. {                   1422 Elkgrove Circle, #3                         }
  7. {                   Venice, CA  90291                                }
  8. { All Rights Reserved                                                }
  9.  
  10. { This unit provides almost everything that is necessary to remove a }
  11. { resident program from memory.  Examine the provided example NODICE }
  12. { to see how easy it is to use.                                      }
  13.  
  14. Interface
  15.  
  16. Uses Dos;
  17.  
  18. Function Installed(MultId : Byte) : Boolean;
  19.  
  20. { Returns true if the resident program with the matching I.D. is loaded. }
  21.  
  22. Function  OkToRemove(MultID : Byte) : Boolean;
  23.  
  24. { Returns true if it is safe to unload the resident }
  25. { program with the matching I.D. number.            }
  26.  
  27. Procedure RemoveProgram(MultID : Byte);
  28.  
  29. { Removes the program with the matching I.D. from memory. }
  30.  
  31. Implementation
  32.  
  33. Type
  34.   VectorTable = Record
  35.                   Number : Byte;
  36.                   OldInt : Pointer;
  37.                   Offset : Word;
  38.                 End;
  39.   VectorArray = Array[1..2] of VectorTable;
  40.   VectorPtr = ^VectorArray;
  41.  
  42. Function DosVersion : Word;
  43.  
  44. { Returns the DOS version as a word.  It swaps the two bytes }
  45. { to make tests more logical, i.e. DosVersion < $0300        }
  46.  
  47.   InLine($B4/$30/    { mov   ah,30h  }
  48.          $CD/$21/    { int   21h     }
  49.          $86/$E0);   { xchg  ah,al   }
  50.  
  51. {==========================================================}
  52. { The following routines should only be called after it is }
  53. { verified that the program is active by calling INSTALLED }
  54. { Running these without the program being active could be  }
  55. { dangerous!                                               }
  56. {==========================================================}
  57.  
  58. Function CheckSignature(MultId : Byte) : Byte;
  59.  
  60. { Returns true a status byte indicating if the program is loaded }
  61.  
  62.   InLine($58/       { pop    ax    }
  63.          $88/$C4/   { mov    ah,al }
  64.          $B0/$00/   { mov    al,0  }
  65.          $CD/$2F);  { int    2Fh   }
  66.  
  67. Function GetTable(MultId : Byte) : Pointer;
  68.  
  69. { Returns a pointer to the vector table }
  70.  
  71.   InLine($58/       { pop    ax    }
  72.          $88/$C4/   { mov    ah,al }
  73.          $B0/$01/   { mov    al,1  }
  74.          $CD/$2F);  { int    2Fh   }
  75.  
  76. Function GetCseg(MultId : Byte) : Word;
  77.  
  78. { Returns the popup's code segment }
  79.  
  80.   InLine($58/       { pop    ax    }
  81.          $88/$C4/   { mov    ah,al }
  82.          $B0/$02/   { mov    al,2  }
  83.          $CD/$2F);  { int    2Fh   }
  84.  
  85. Procedure ReleaseMemory(MultId : Byte);
  86.  
  87. { Releases the popup's memory }
  88.  
  89.   InLine($58/       { pop    ax    }
  90.          $88/$C4/   { mov    ah,al }
  91.          $B0/$03/   { mov    al,3  }
  92.          $CD/$2F);  { int    2Fh   }
  93.  
  94. Function GetEndOffset(MultId : Byte) : Word;
  95.  
  96. { Returns the popup's code segment }
  97.  
  98.   InLine($58/       { pop    ax    }
  99.          $88/$C4/   { mov    ah,al }
  100.          $B0/$04/   { mov    al,4  }
  101.          $CD/$2F);  { int    2Fh   }
  102.  
  103. {==========================================================}
  104.  
  105. Function Installed(MultID : Byte) : Boolean;
  106.  
  107. { Returns TRUE if the program is active in memory }
  108.  
  109. Var
  110.   TempV : Pointer;
  111.  
  112. Begin
  113.   Installed := False;
  114.   If DosVersion < $0300 Then
  115.   Begin               { DOS 2.x }
  116.     GetIntVec($2F,TempV);
  117.     If TempV = Nil Then Exit;
  118.   End;
  119.   If CheckSignature(MultId) = $FF Then Installed := True;
  120. End;
  121.  
  122. Function  OkToRemove(MultID : Byte) : Boolean;
  123.  
  124. { Returns TRUE if it is safe to remove the program }
  125.  
  126. Var
  127.   OldVector : Pointer;
  128.   NewVector : Pointer;
  129.   Index  : Integer;
  130.   PopCSeg : Word;
  131.   Table : VectorPtr;
  132.   EndOfs : Word;
  133.  
  134. Begin
  135.   OkToRemove := False;
  136.   EndOfs := GetEndOffset(MultId);
  137.   If EndOfs <> MemW[PrefixSeg:$002C] Then Exit;
  138.   PopCSeg := GetCSeg(MultId);
  139.   Table := GetTable(MultId);
  140.   Index := 1;
  141.   While Table^[Index].Number <> 0 Do
  142.  
  143.   { compares the current value of the interrupt vector with what the  }
  144.   { resident program set it to.  If ALL of them are unchanged then it }
  145.   { is safe to remove the program from memory.                        }
  146.  
  147.   Begin
  148.     GetIntVec(Table^[Index].Number,NewVector);
  149.     OldVector := Ptr(PopCSeg,Table^[Index].Offset);
  150.     If OldVector <> NewVector Then Exit;
  151.     Inc(Index);
  152.   End;
  153.   OkToRemove := True;
  154. End;
  155.  
  156. Procedure RemoveProgram(MultID : Byte);
  157.  
  158. { Removes the program from memory }
  159.  
  160. Var
  161.   Index   : Integer;
  162.   Table   : VectorPtr;
  163.  
  164. Begin
  165.   ReleaseMemory(MultID);              { release the memory }
  166.   Table := GetTable(MultId);
  167.   Index := 1;
  168.   While Table^[Index].Number <> 0 Do  { restore the interrupt vectors }
  169.   Begin
  170.     SetIntVec(Table^[Index].Number,Table^[Index].OldInt);
  171.     Inc(Index);
  172.   End;
  173. End;
  174.  
  175. End.
  176.